package org.openapi.controller;

import org.openapi.common.ApiResult;
import org.openapi.consts.ApiConst;
import org.openapi.service.IApiLoaderService;
import org.openapi.service.IOpenApiService;
import org.openapi.service.IOpenDataService;
import org.openapi.service.IOpenExcelService;
import org.openapi.utils.IoUtil;
import org.openapi.utils.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * 开放数据接口
 */
public class OpenDataController
{
    @Autowired
    private IOpenApiService openApiService;
    @Autowired
    private IOpenDataService openDataService;
    @Autowired
    private IApiLoaderService apiLoaderService;

    @Autowired
    private IOpenExcelService openExcelService;

    /**
     * 标准Restful
     */
    @RequestMapping("/")
    public ApiResult curd(HttpServletRequest request, @RequestBody(required = false) String body)
    {
        return openDataService.run(request, body);
    }

    /**
     * 标准Restful
     */
    @GetMapping("/{query}")
    public ApiResult curd(@PathVariable("query") String query)
    {
        return ApiResult.success(openDataService.doGet(query));
    }

    /**
     * 查询
     */
    @RequestMapping("/get")
    public ApiResult get(@RequestBody String query)
    {
        return ApiResult.success(openDataService.doGet(query));
    }

    /**
     * 新增
     */
    @RequestMapping("/post")
    public ApiResult post(@RequestBody String body)
    {
        return ApiResult.success(openDataService.doPost(body));
    }

    /**
     * 更新
     */
    @RequestMapping("/put")
    public ApiResult put(@RequestBody String body)
    {
        return ApiResult.success(openDataService.doPut(body));
    }

    /**
     * 更新或新增
     */
    @RequestMapping("/patch")
    public ApiResult patch(@RequestBody String body)
    {
        return ApiResult.success(openDataService.doPatch(body));
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    public ApiResult delete(@RequestBody String body)
    {
        return ApiResult.success(openDataService.doDelete(body));
    }

    /**
     * 查询数据源
     */
    @GetMapping("/ds/{code}")
    public ApiResult ds(@PathVariable("code") String code, @RequestParam Map data)
    {
        return ApiResult.success(openDataService.doDs(code, data));
    }

    /**
     * 重载缓存
     */
    @GetMapping("/load/{type}")
    public ApiResult load(@PathVariable("type") String type)
    {
        if(!openApiService.isAdmin()){
            return ApiResult.error("您没有权限");
        }
        if(type.equalsIgnoreCase("MODEL")){
            apiLoaderService.loadModel();
        }else if(type.equalsIgnoreCase("EVENT")){
            apiLoaderService.loadEvent();
        }else if(type.equalsIgnoreCase("SQL")){
            apiLoaderService.loadSql();
        }else{
            ApiResult.error("不支持的业务类型");
        }
        return ApiResult.success();
    }

    /**
     * 生成导出excel文件
     */
    @PostMapping("/export")
    public ApiResult export(@RequestBody String body)
    {
        String fileName = openExcelService.exports(body);
        if(fileName == null){
            return ApiResult.error("生成导出文件出错");
        }else{
            return ApiResult.success(StrUtil.encode64(fileName));
        }
    }

    /**
     * 下载文件，一般是导出的excel
     */
    @GetMapping("/down/{fileName}")
    public void down(@PathVariable("fileName") String fileName, HttpServletResponse response)
    {
        try
        {
            fileName = StrUtil.decode64(fileName);

            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);

            String encode = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
            String percentEncodedFileName = encode.replaceAll("\\+", "%20");

            StringBuilder contentDispositionValue = new StringBuilder();
            contentDispositionValue.append("attachment; filename=")
                    .append(percentEncodedFileName)
                    .append(";")
                    .append("filename*=")
                    .append("utf-8''")
                    .append(percentEncodedFileName);

            response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename");
            response.setHeader("Content-disposition", contentDispositionValue.toString());
            response.setHeader("download-filename", percentEncodedFileName);

            String filePath = openApiService.getUploadPath(ApiConst.EXCEL_FOLDER)+fileName;
            IoUtil.writeBytes(filePath, response.getOutputStream());
            IoUtil.deleteFile(filePath);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * 导入excel数据
     * @param file
     * @param model
     * @param updateSupport
     * @return
     * @throws Exception
     */
    @PostMapping("/imports")
    public ApiResult imports(MultipartFile file, String model, boolean updateSupport) throws Exception
    {
        int rows = openExcelService.imports(file.getInputStream(), model, updateSupport);
        return ApiResult.success("成功导入"+rows+"条数据");
    }

    /**
     * 生成excel导入模板
     * @param model
     * @return
     */
    @GetMapping("/template")
    public ApiResult template(String model)
    {
        String fileName = openExcelService.template(model);
        if(fileName == null){
            return ApiResult.error("生成模板文件出错");
        }else{
            return ApiResult.success(StrUtil.encode64(fileName));
        }
    }
}
